public class DrawUtil {
	public interface XZConsumer {
		void accept(int x, int z);
	}

	// (tx - x) * dz == (tz - z) * dx
	public static void drawLine(final float sx, final float sz, final float tx, final float tz,
								final XZConsumer callback) {
		final double dx = (double)tx - sx, dz = (double)tz - sz, d = Math.sqrt(dx * dx + dz * dz);
		final double stepCountX, stepCountZ;
		final int stepX, stepZ;
		double countX, countZ;
		int x = (int)Math.floor(sx);
		int z = (int)Math.floor(sz);
		//@formatter:off
		if (dx < 0) { stepX = -1; stepCountX = -d / dx; countX = stepCountX * (sx - x); }
		else        { stepX =  1; stepCountX =  d / dx; countX = stepCountX * (x - sx + 1); }
		if (dz < 0) { stepZ = -1; stepCountZ = -d / dz; countZ = stepCountZ * (sz - z); }
		else        { stepZ =  1; stepCountZ =  d / dz; countZ = stepCountZ * (z - sz + 1); }
		//@formatter:on
		final int txi = (int)Math.floor(tx);
		final int tzi = (int)Math.floor(tz);
		for (; ; ) {
			callback.accept(x, z);
			if (x == txi && z == tzi)
				return;
			if (countX < countZ) {
				countX += stepCountX;
				x += stepX;
			} else {
				countZ += stepCountZ;
				z += stepZ;
			}
		}
	}

	public static void main(String[] args) {
		drawLine(1.1f, 1.9f, 5.1f, 5.9f, (x, z) -> System.out.println(x + ", " + z));
		System.out.println("---");
		drawLine(1.1f, 1.9f, 1.1f, 5.9f, (x, z) -> System.out.println(x + ", " + z));
		System.out.println("---");
		drawLine(1.1f, 1.9f, 5.1f, 1.9f, (x, z) -> System.out.println(x + ", " + z));
		System.out.println("---");
		drawLine(1.1f, 1.9f, 1.1f, 1.9f, (x, z) -> System.out.println(x + ", " + z));
		System.out.println("---");
		drawLine(-1.1f, -1.9f, -5.1f, -5.9f, (x, z) -> System.out.println(x + ", " + z));
	}
}
